﻿package {

	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.events.NetStatusEvent;
	import flash.net.GroupSpecifier;
	import flash.net.NetConnection;
	import flash.net.NetGroup;
	import flash.net.NetGroupReplicationStrategy;
	import flash.text.TextFormat;
	
	import fl.controls.Button;
	import fl.controls.Label;
	import fl.controls.TextArea;
	
	import fla.view.P2PView;


	public class p2p_HelloWorld extends Sprite {
		
		private var _lbl:Label;
		private var _btnAddToWant:Button;
		private var _btnGenData:Button;
		private var _btnAddToHave:Button;
		private var _txtObj:TextArea;
		private var _txtOutput:TextArea;
		private var _data:Vector.<String>;
		private var _dataLength:uint = 100;
		private var _nc:NetConnection;
		private var _ng:NetGroup;
		private var _spec:GroupSpecifier;
		private var _server:String = "rtmfp://localhost/test";
		private var _groupName:String = "myGroup";
		private var _connected:Boolean = false;
		
		public var p2pview:P2PView = new P2PView();

		public function p2p_HelloWorld(){
			init();
		}

		private function init():void {
			addChild(p2pview);
			
			this._btnAddToWant = p2pview.btnAddToWant;
			this._btnAddToHave = p2pview.btnAddToHave;
			this._btnGenData = p2pview.btnGenData;
			this._txtObj = p2pview.txtObj;
			this._txtOutput = p2pview.txtOutput;
			this._lbl = p2pview.lbl;
			
			var style:TextFormat = new TextFormat("宋体", 12, 0x000000,false,false,false,null,null,null,null,null,null,5);
			this._btnAddToHave.setStyle("textFormat", style);
			this._btnAddToWant.setStyle("textFormat", style);
			this._btnGenData.setStyle("textFormat", style);
			this._txtObj.setStyle("textFormat", style);
			this._txtOutput.setStyle("textFormat", style);
			this._lbl.setStyle("textFormat", style);
			
			this._btnGenData.addEventListener(MouseEvent.CLICK, _btnGenData_Click);
			this._btnAddToHave.addEventListener(MouseEvent.CLICK, _btnAddToHave_Click);
			this._btnAddToWant.addEventListener(MouseEvent.CLICK, _btnAddToWant_Click);

			//先连接到服务器
			_nc = new NetConnection();
			_nc.addEventListener(NetStatusEvent.NET_STATUS, _nc_Net_Status);
			_nc.connect(_server);
			output("正在连接 " + _server + " ...");
		}

		private function _nc_Net_Status(e:NetStatusEvent):void {
			output(e.info.code);
			switch (e.info.code){
				case "NetConnection.Connect.Success":	
					//连接成功后，要设置NetGroup
					this._spec = new GroupSpecifier(this._groupName);					
					_spec.serverChannelEnabled = true;//设置允许创建到服务端的通道
					_spec.objectReplicationEnabled = true;//允许对象复制
					_ng = new NetGroup(_nc, _spec.groupspecWithAuthorizations());
					_ng.addEventListener(NetStatusEvent.NET_STATUS, _nc_Net_Status);
					break;
				case "NetGroup.Connect.Success":
					_connected = true;
					_ng.replicationStrategy = NetGroupReplicationStrategy.LOWEST_FIRST;//设置数据块传输时，先传递索引号最小的块
					break;
				case "NetGroup.Replication.Fetch.SendNotify": 
					//每当"接收方"有数据到达(但尚未开始接收)时，将触发此处理
					output("    -->通知：数据块 " + e.info.index + "  即将被接收");
					break;
				case "NetGroup.Replication.Fetch.Failed": 
					//“接收方”有数据接收失败时，将触发此处理
					output("    -->错误：数据块 " + e.info.index + " 接收失败");
					break;
				case "NetGroup.Replication.Fetch.Result": 
					//“接收方”每次成功接收到数据时，触发此段处理
					output("    -->数据块 " + e.info.index + " 已成功接收，值：" + e.info.object);
					_ng.addHaveObjects(e.info.index, e.info.index);	//接收完成以后，将接收到的数据加入“待发送对象列表"中，这样人越多，传输越稳定，速度也越快	
					if (_data == null) {
						_data = new Vector.<String>(this._dataLength);
					}
					_data[e.info.index] = e.info.object.toString();
					//说明全部接收完了
					if (e.info.index == this._dataLength - 1) {
						for (var i:int = 0; i < _dataLength; i++){
							_data[i] = "这是数据 " + i.toString();
							this._txtObj.appendText("index:" + i.toString() + "，data:" + _data[i] + " | ");
						}
					}
					break;
				case "NetGroup.Replication.Request": 
					//每当有数据传输请求时，“提供方”将触发此处理
					_ng.writeRequestedObject(e.info.requestID, _data[e.info.index]);//这里才是真正的响应“接收方"，将指定的数据发送过去
					output("    -->数据块 " + e.info.index + " 请求被发送，本次请求ID：" + e.info.requestID);
					break;
				default:
					break;
			}
		}

		//初始化生成数据
		private function _btnGenData_Click(e:MouseEvent):void {
			this._txtObj.text = "";
			if (_data==null){
				_data = new Vector.<String>(this._dataLength);
			}
			for (var i:int = 0; i < _dataLength; i++){
				_data[i] = "这是数据 " + i.toString();
				this._txtObj.appendText("index:" + i.toString() + "，data:" + _data[i] + " | ");
			}
		}
		
		//将生成的初始数据，添加到待发送的“列表”中
		private function _btnAddToHave_Click(e:MouseEvent):void 
		{
			this._ng.addHaveObjects(0, _dataLength - 1);
		}
		
		//请求接收数据
		private function _btnAddToWant_Click(e:MouseEvent):void
		{
			this._ng.addWantObjects(0, _dataLength - 1);
		}

		//输出结果
		private function output(s:String):void {
			this._txtOutput.appendText(s + "\n");
		}
	}

}
